package controller

import (
	"fmt"
	"image/png"
	"strings"
	"time"
	"uap/common"
	"uap/pkg/app"

	"github.com/gin-gonic/gin"
	"github.com/google/uuid"
	"github.com/skip2/go-qrcode"
)

var (
	BarScanStatus         = make(map[string]int)
	ScanTimeout       int = 0
	ScanStatusWaiting int = 1
	ScanStatusDoing   int = 2
	ScanStatusSuccess int = 3
	ScanStatusFailed  int = 4
)

type Qrcode struct {
}

func NewQrcode() *Qrcode {
	return &Qrcode{}
}

type ScanStatusVo struct {
	Status int `json:"status"`
	// UapUserId   string `json:"uapUserId"`
	CallbackUrl string `json:"callbackUrl"`
	// AppId       string `json:"appId"`
	Code string `json:"code"`
}

// 生成登录二维码
func (a *Qrcode) CreateLoginQrcode(c *gin.Context) {
	deviceId := c.DefaultQuery("deviceId", "")
	appId := c.DefaultQuery("appId", "")
	scanStatusVo := ScanStatusVo{Status: ScanStatusWaiting}
	common.ScanStatusCache.Set(deviceId, &scanStatusVo, time.Second*60)
	var tbApp TbApp
	common.Db.Table("tb_app").Where("app_id = ?", appId).First(&tbApp)
	if tbApp.AppName == "" {
		app.Error(c, app.AppNotExist.Code, app.AppNotExist.Msg)
		return
	}
	re := fmt.Sprintf("appId=%s&deviceId=%s&type=login", appId, deviceId)
	qrcode, err := qrcode.New(re, qrcode.Low)
	if err != nil {
		fmt.Println(err)
	}
	png.Encode(c.Writer, qrcode.Image(256))
}

// 生成注册二维码
func (a *Qrcode) CreateRegisterQrcode(c *gin.Context) {
	appId := c.DefaultQuery("appId", "")
	deviceId := c.DefaultQuery("deviceId", "")
	scanStatusVo := ScanStatusVo{Status: ScanStatusWaiting}
	common.ScanStatusCache.Set(deviceId, &scanStatusVo, time.Second*60)
	var tbApp TbApp
	common.Db.Table("tb_app").Where("app_id = ?", appId).First(&tbApp)
	if tbApp.AppName == "" {
		app.Error(c, app.AppNotExist.Code, app.AppNotExist.Msg)
		return
	}
	re := fmt.Sprintf("appId=%s&deviceId=%s&type=register", appId, deviceId)
	qrcode, err := qrcode.New(re, qrcode.Low)
	if err != nil {
		fmt.Println(err)
	}
	png.Encode(c.Writer, qrcode.Image(256))
}

// 扫描二维码后，还未点击授权按钮
func (a *Qrcode) ScanBeforeOption(c *gin.Context) {
	deviceId := c.DefaultQuery("deviceId", "")
	appId := c.DefaultQuery("appId", "")
	//验证QRcode
	var scanStatusVo *ScanStatusVo
	res, ok := common.ScanStatusCache.Get(deviceId)
	if ok {
		scanStatusVo = res.(*ScanStatusVo)
		if scanStatusVo.Status == ScanTimeout {
			app.Error(c, app.QrcodeExpired.Code, app.QrcodeExpired.Msg)
			return
		}
		var tbApp TbApp
		common.Db.Table("tb_app").Where("app_id = ? ", appId).First(&tbApp)
		scanStatusVo.Status = ScanStatusDoing
		common.ScanStatusCache.Set(deviceId, &scanStatusVo, time.Second*60)
		app.Success(c, tbApp)
		return
	} else {
		app.Error(c, app.QrcodeExpired.Code, app.QrcodeExpired.Msg)
		return
	}
}

// 扫二维码后点击授权登录按钮
func (a *Qrcode) ScanAfterOption(c *gin.Context) {
	appId := c.DefaultQuery("appId", "")
	deviceId := c.DefaultQuery("deviceId", "")
	userId := c.DefaultQuery("userId", "")
	typeStr := c.DefaultQuery("type", "")

	//验证应用
	var tbApp TbApp
	common.Db.Table("tb_app").Where("app_id = ?", appId).First(&tbApp)
	if tbApp.AppName == "" {
		app.Error(c, app.AppNotExist.Code, app.AppNotExist.Msg)
		return
	}
	if typeStr == "login" {
		//验证用户
		var userAuth TbUserAuth
		common.Db.Table("tb_user_auth").Where("user_id = ? and app_id = ? ", userId, appId).First(&userAuth)
		if userAuth.AppId == "" {
			scanStatusVo := ScanStatusVo{Status: ScanTimeout}
			common.ScanStatusCache.Set(deviceId, &scanStatusVo, time.Second*60)
			app.Error(c, app.AppNotExistUser.Code, app.AppNotExistUser.Msg)
			return
		}
	} else if typeStr == "register" {
		var userAuth TbUserAuth
		common.Db.Table("tb_user_auth").Where(" app_id=? and user_id = ?", appId, userId).First(&userAuth)
		if userAuth.AppId != "" {
			app.Error(c, app.AppHasGrantUser.Code, app.AppHasGrantUser.Msg)
			return
		}
		userAuth.CreateDate = time.Now().Format("2006-01-02 15:04:05")
		userAuth = TbUserAuth{AppId: appId, UserId: userId}
		common.Db.Table("tb_user_auth").Create(&userAuth)
	}
	code := strings.ReplaceAll(uuid.NewString(), "-", "")
	common.CodeCache.Set(code, userId, time.Minute*5)
	scanStatusVo := ScanStatusVo{Status: ScanStatusSuccess, Code: code}
	common.ScanStatusCache.Set(deviceId, &scanStatusVo, time.Second*60)
	app.Success(c, "")
}

// 轮询扫码状态
func (a *Qrcode) ScanStatus(c *gin.Context) {
	deviceId := c.DefaultQuery("deviceId", "")
	scanStatusVo, ok := common.ScanStatusCache.Get(deviceId)
	if ok {
		app.Success(c, scanStatusVo)
	} else {
		scanStatusVo = ScanStatusVo{Status: ScanTimeout}
		app.Success(c, scanStatusVo)
	}
}
